'use strict';

(() => {
    const util = new Util();

    /**
     * Match url by given regex
     * 
     * @param {String} url the url for test
     */
    function matchUrl(url) {
        // return /.+bbs.gfan.com\/android.+/.test(url);
        return url.indexOf('bbs.gfan.com/android-') != -1;
    }


    /**
     * 储存已刷新tabId 避免重复回复
     */
    function TabIdStore() {
        this.store = [];
        this.add = (id) => {
            if (this.store.includes(id)) {
                return false;
            }
            this.store.push(id);
            return true;
        };
        this.inject = (id) => {
            this.store = this.store.filter(item => item != id);
        }
    };

    /**
     * 储存回复失败请求的队列， 15秒间隔后重新尝试回复
     */
    function RequestQueue() {
        this.successTime = 0;
        this.isPoll = false;
        this.queues = [];
        this.map = new Map();
        this.add = (tabId, params) => {
            if (!this.isPoll) {
                this.poll();
            }
            if (!this.queues.includes(tabId)) {
                this.queues.push(tabId);
                this.map.set(tabId, params);
            }
        };
        this.isExist = (tabId) => {
            return this.queues.includes(tabId);
        };

        /**
         * 更新上次成功回复时间
         */
        this.updateSuccessTime = () => {
            this.successTime = Date.now();
        };

        // 判断是否可以回复
        this.canIReply = () => {
            return Date.now() - this.successTime > 15000;
        }

        this.poll = () => {
            this.isPoll = true;
            let id = setInterval(() => {
                console.log('polling...');
                if (this.queues.length == 0) {
                    this.isPoll = false;
                    clearInterval(id);
                    return;
                }
                if (this.queues.length > 0 && this.canIReply()) {
                    console.log(this.queues, this.map);
                    let tabId = this.queues.shift();
                    replyWithParams(tabId, this.map.get(tabId));
                    this.map.delete(tabId);
                };
            }, 2000);
        }

    };

    var tabIdStore = new TabIdStore();
    var requestQueue = new RequestQueue();

    /**
     * 发起回复给定帖子的请求
     * 
     * @param {Object} params 回帖请求的url、所需formhash
     */
    function replyWithParams(tabId, params) {
        if (!requestQueue.canIReply()) {
            // 回复时间小于15秒
            tabIdStore.inject(tabId);
            util.toast('回复太快！', tabId);
            return;
        }


        let { url, data } = params;
        // 发起请求
        $.post(url, data, (data) => {
            // 回复失败
            if (data.indexOf('errorhandle_fastpost') != -1 || data.indexOf('抱歉，您尚未登录，没有权限在该版块回帖') != -1) {
                // 失败原因：未登录
                if (data.indexOf('未登录') != -1) {
                    util.toast('未登录', tabId);
                }
                tabIdStore.inject(tabId);
                return;
            }

            if (data.indexOf('抱歉，您两次发表间隔少于 15 秒，请稍候再发表') != -1) {
                requestQueue.add(tabId, params);
                util.toast('抱歉，您两次发表间隔少于 15 秒，请稍候再发表', tabId);
                return;
            }

            if (data.indexOf('抱歉，您的帖子小于 10 个字符的限制') != -1) {
                setTimeout(() => {
                    tabIdStore.inject(tabId);
                }, 4000);
                util.toast('抱歉，您的帖子小于 10 个字符的限制', tabId);
                return;
            }

            // 回复成功 返回状态码301 Moved Permanently
            // console.log(res);
            requestQueue.updateSuccessTime();
            setTimeout(() => {
                util.toast('自动回帖成功', tabId);
            }, 1000);
            setTimeout(() => {
                tabIdStore.inject(tabId);
            }, 4000);
            chrome.tabs.executeScript(tabId, { code: 'window.location.reload(true);' });
        })
    };

    function replyHandler(tabId) {
        chrome.tabs.executeScript(
            tabId,
            { file: 'src/gfan/tabs/queryReplyParamsFastPost.js' },
            ([params]) => {
                chrome.storage.sync.get('gfan', ({ gfan }) => {
                    let opts = {};
                    opts.url = `http://bbs.gfan.com/${params.url}`;
                    opts.data = {
                        message: gfan.reply.replyMsg || new Date().toString(),
                        posttime: Date.now(),
                        formhash: params.formhash,
                    };

                    replyWithParams(tabId, opts);
                })
            }
        );
    }

    // handle on tab is updated
    function tabs_on_updated(tabId, changeInfo, tab) {
        // do not something when url is not matched
        if (!matchUrl(tab.url) || !tabIdStore.add(tabId) || requestQueue.isExist(tabId)) return;
        console.log(tabId);

        chrome.storage.sync.get('gfan', ({ gfan }) => {
            // 判断是否回复所有帖
            if (gfan.reply.isReplyAllPosting) {
                console.log('Reply all posting...');
                replyHandler(tabId);
            } else {
                // 只回复需回复帖

                chrome.tabs.executeScript(
                    tabId,
                    { code: 'document.getElementsByClassName("locked");' },
                    (resultArray) => {
                        // 判断当前帖是否是未回复帖
                        if (resultArray) {
                            console.log('Reply locked posting...');
                            replyHandler(tabId)
                        };
                    })
            }
        });
    }

    // handle on extension is installed
    function runtime_on_installed() {
        // 装载配置文件
        $.get('json/config.json', (data) => {
            chrome.storage.sync.set(data, () => {
                console.info('Loading conifg file: ', data);
            })
        })

        // 创建上下文菜单
        // var menus = [
        //     { id: 'head', title: 'Cotext Menus', contexts: ['page'], enabled: false },
        //     { id: 'bbs.gfan.com', title: 'Bbs.gfan.com', documentUrlPatterns: ['*://bbs.gfan.com/*'], contexts: ['page'] },
        //     { id: 'reply', title: 'Reply', contexts: ['page'], parentId: 'bbs.gfan.com' },
        //     { id: 'test', title: 'Test', contexts: ['page'] }
        // ]
        let menus = [
            { id: 'reply', title: 'Reply', documentUrlPatterns: ['*://bbs.gfan.com/*'], contexts: ['page'] }
        ]
        for (const menu of menus) {
            chrome.contextMenus.create(menu);
        }
    }

    // handle on context menus is clicked
    function context_menus_on_clicked(info, tab) {
        // console.log(info, tab);
        let tabId = tab.id;
        if (!tabIdStore.add(tabId) || requestQueue.isExist(tabId)) {
            util.toast('已加入回复队列，请勿重复提交!', tabId);
            return;
        }
        replyHandler(tabId);
    };

    function web_request_on_before_request(details) {
        console.log(details);
        if ("xmlhttprequest" == details.type) {
            return;
        }
        $.get(details.url).then(res => {
            let html = new DOMParser().parseFromString(res, 'text/html');
            let $html = $(html);
            let action = $html.find('#fastpostform').attr('action');
            let formhash = $html.find('#fastpostform input[name="formhash"]').val();

            console.log(action, formhash);
        })



        return { cancel: true }
    }

    // Add listener on updated of tabs
    chrome.tabs.onUpdated.addListener(tabs_on_updated);
    chrome.contextMenus.onClicked.addListener(context_menus_on_clicked)
    chrome.runtime.onInstalled.addListener(runtime_on_installed);
    chrome.webRequest.onBeforeRequest.addListener(
        web_request_on_before_request,
        {
            urls: ["*://bbs.gfan.com/forum-*"]
        }
    )

})();